/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.rolgps.libns.server;


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.rolgps.libnstack.protocol.Message;

/**
 *
 * @author xeph
 */
public class ServerEndpoint implements Runnable{

    private ServerSocket srvSock = null;
    private boolean keepListening=true;
    private int portNo=4321;
    BlockingQueue<Message> messageQueue = new LinkedBlockingQueue<Message>();


    /**
     *
     * @throws java.io.IOException
     */
    public ServerEndpoint() throws IOException {
        srvSock= new ServerSocket(portNo);
    }

    /**
     *
     * @param port
     * @throws java.io.IOException
     */
    public ServerEndpoint(int port) throws IOException{
        this.portNo=port;
        srvSock= new ServerSocket(portNo);
    }

    /**
     * 
     */
    public void run() {
        //DO NOT FUCKING JOIN THE THREAD.
        MessageDispatcher dispatcher = new MessageDispatcher(messageQueue);
        Thread messageDispatcherThread = new Thread(dispatcher);
        messageDispatcherThread.setDaemon(true);
        messageDispatcherThread.start();
        while(keepListening){
            try {
                Socket primaryConnection = srvSock.accept();
                new Thread(new SocketListener(primaryConnection, messageQueue)).start();
                SocketSender socketSender = new SocketSender(primaryConnection);
                dispatcher.addObserver(socketSender);
                new Thread(socketSender).start();
            } catch (IOException ex) {
                Logger.getLogger(ServerEndpoint.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        try {
            srvSock.close();
        } catch (IOException ex) {
            Logger.getLogger(ServerEndpoint.class.getName()).log(Level.SEVERE, null, ex);
        }
    }




}
